#include "pch.h"
#include "GuiEngine.h"
#include "GuiEntity.h"
#include "GraphicEngine.h"
#include "WLEngine.h"
#include "UIFactory.h"

namespace WL
{
	std::list<CGuiEntity*>	CGuiEngine::mGuiEntites;
	std::list<CGuiEntity*>	CGuiEngine::mShowGuiEntites;
	CGuiEngine::CGuiEngine()
	{
		mpFactory = CUIFactory::createInstance();
	}

	CGuiEngine::~CGuiEngine()
	{
		mpFactory = nullptr;
		CUIFactory::destory();
	}

	bool CGuiEngine::initialize()
	{
		return true;
	}

	void CGuiEngine::unInitialize()
	{

	}

	void CGuiEngine::addGuiEntity(CGuiEntity* pGui)
	{
		mGuiEntites.push_back(pGui);
		if (pGui->isVisible())
		{
			mShowGuiEntites.push_back(pGui);
		}
	}

	void CGuiEngine::removeGuiEntity(CGuiEntity* pGui)
	{
		auto item = std::find(mGuiEntites.begin(), mGuiEntites.end(), pGui);
		if (item != mGuiEntites.end())
		{
			mGuiEntites.erase(item);
			item = std::find(mShowGuiEntites.begin(), mShowGuiEntites.end(), pGui);
			if (item != mShowGuiEntites.end())
			{
				mShowGuiEntites.erase(item);
			}
		}
	}

	bool CGuiEngine::processMsg(event& e)
	{
		if(MSG_KEYUP == e.message )
		{
			auto iter = mShortCuts.find((CHAR)e.wParam);
			if (iter != mShortCuts.end())
			{

			}
		}
		auto pGui = nullptr;
		for( auto item : mShowGuiEntites)
		{
			int nPickId = item->mpUIWnd->_pick(e);
			if (-1 != nPickId)	
			{
				lua_State* pLua = GEngine->getLuaState();
				int nTop = lua_gettop(pLua);
				lua_getglobal(pLua, item->mLuaTableName.c_str());
				if (lua_istable(pLua, -1))
				{
					lua_getfield(pLua, -1, "msgProcess");
					if (lua_isfunction(GEngine->getLuaState(), -1))
					{
						switch (e.message)
						{
						case MSG_MOUSEMOVE:
						case MSG_LBUTTONDOWN:
						case MSG_LBUTTONUP:
						case MSG_RBUTTONDOWN:
						case MSG_RBUTTONUP:
						case MSG_KEYDOWN:
						case MSG_KEYUP:
						case MSG_CHAR:
							lua_pushvalue(pLua, -2);
							lua_pushinteger(pLua, e.message);
							lua_pushinteger(pLua, nPickId);
							if (lua_pcall(pLua, 3, 1, 0) == LUA_OK)
							{
								int nRet = static_cast<int>(lua_tointeger(pLua, -1));
								e.bProcess = nRet == 0 ? false : true;
							}
							break;
						}
						lua_settop(pLua, nTop);
					}
				}
				break;
			}
		}
		if (!e.bProcess)
		{
			GEngine->reviceMsg(e);
		}
		return e.bProcess;
	}

	CUIWnd* CGuiEngine::createUI(WndType type)
	{
		return mpFactory->createUI(type);
	}

	void CGuiEngine::registerShortCuts(CHAR k, const std::string& szFunction)
	{
		mShortCuts[k].first = szFunction;
	}

	void CGuiEngine::registerShortCuts(CHAR k, std::function<bool(CHAR)> function)
	{
		mShortCuts[k].second = function;
	}

	void CGuiEngine::_update(UINT32 dTime)
	{
	}

}
